﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace ServerFrame
{
    public delegate void SendDE(SocketAsyncEventArgs e);
    public delegate void CloseToken(MyToken token, string error);

    public class MyToken
    {
        public SocketAsyncEventArgs read_arg, writeArg;

        public Socket socket;
        public Queue<TransModel> wqueue=new Queue<TransModel>();
        public AbsMessageCenter center;

        public SendDE send_de;  //定义一个委托
        public CloseToken close_de; //这个看看用好了没有

        //消息的接收缓存
        List<byte> cache = new List<byte>();

        bool isRead = false;    //判断是否在读
        bool isWrite = false;

        public MyToken() {
            read_arg = new SocketAsyncEventArgs();
            writeArg = new SocketAsyncEventArgs();

            read_arg.UserToken = this;
            writeArg.UserToken = this;

            read_arg.SetBuffer(new byte[1024], 0, 1024);
        }

        public void Close() {
            try
            {

                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                socket = null;

            }
            catch (Exception ex) {
                Console.WriteLine(ex.ToString());
            }
        }

        public void Recevie(byte[] data) {
            cache.AddRange(data);
            if (isRead == false) {
                isRead = true;
                Read();
            }
        }

        //todo读方法
        public void Read() {            
            byte[] value = LengthE_D.LengthDecode(ref cache);
            if (value == null)
            {
                isRead = false;
                return;
            }
            else {
                TransModel model = (TransModel)TransModelE_D.TransDecode_de(value);
                if (model == null) {
                    isRead =false;
                    return;
                }

                //todo通知上层应用，消息到达
                center.OnMessageReceive(this, model);
                Read(); //递归，继续读取消息
            }
        }

        //
        public void Send(TransModel model) {
            wqueue.Enqueue(model);

            if (isWrite == false) {
                isWrite = true;
                Write();              
            }
        }

        public void Write() {
            if (wqueue.Count <= 0) {
                isWrite = false;
                return;
            }

            TransModel model = wqueue.Dequeue();//移除并写入

            //传输模型编码
            byte[] value = TransModelE_D.TransEncode_de(model);
            if (value == null) {
                isWrite = false;
                return;
            }

            //长度的编码
            byte[] result = LengthE_D.LengthEncode(value);
            if (result == null) {
                isWrite = false;
                return;
            }

            writeArg.SetBuffer(result, 0, result.Length);
            try
            {
                bool v = socket.SendAsync(writeArg);
                if (v == false)
                {
                    //SendDE(writeArg);
                    send_de(writeArg);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}
